--- ========================================================= ---
---  Setup Revision, Version, Date and add to AceLibrary
--- ========================================================= ---
local VERSION = tonumber(("$Revision: 52619 $"):match("%d+"))

local DaHud = DaHud
DaHud_Module_Model = DaHud:NewModule("Module_Model", "AceEvent-2.0")
local self = DaHud_Model
if DaHud.revision < VERSION then
	DaHud.version = "r" .. VERSION
	DaHud.revision = VERSION
	DaHud.date = ("$Date: 2007-10-19 21:07:04 -0400 (Fri, 19 Oct 2007) $"):match("%d%d%d%d%-%d%d%-%d%d")
end
DaHud.desc = "Model Module"

--- ========================================================= ---
---  Setup Locals
--- ========================================================= ---
local L = DaHud:L("DaHud_Module_Model")

--- ========================================================= ---
---  On Intitalize / Setup Database
--- ========================================================= ---
function DaHud_Module_Model:OnInitialize()
	self.db = DaHud:AcquireDBNamespace("Module_Model")
	DaHud:RegisterDefaults("Module_Model", "profile", {
		number = 1,
		hudmodel1 = {"Target", true, "LOW", 4, 100, 100, 1, 0, -295, "target", false, "always"},
	})
end

--- ========================================================= ---
---  On Enable
--- ========================================================= ---
function DaHud_Module_Model:OnEnable()
	self:SetupOptions()
	self:CreateFrames()
	self:UpdateAllFrames()
	
	self:RegisterEvent("DaHud_SetConfigMode")
	self:RegisterEvent("DaHud_ReloadAllFrames")
end

--- ========================================================= ---
---  On Disable
--- ========================================================= ---
function DaHud_Module_Model:OnDisable()
	self:UnregisterAllEvents();
end

--- ========================================================= ---
---  DaHud_SetConfigMode
--- ========================================================= ---
function DaHud_Module_Model:DaHud_SetConfigMode()
	self:UpdateAllFrames()
end

--- ========================================================= ---
---  DaHud_ReloadAllFrames
--- ========================================================= ---
function DaHud_Module_Model:DaHud_ReloadAllFrames()
	self:SetupOptions()
	self:UpdateAllFrames()
end

--- ========================================================= ---
---  Setup Validates for Options
--- ========================================================= ---
local strataValidate = {
	BACKGROUND = L["Background"],
	LOW = L["Low"],
	MEDIUM = L["Medium"],
	HIGH = L["High"],
	DIALOG = L["Dialog"],
	TOOLTIP = L["Tooltip"],
}

local strataValidateDesc = {}

local eventUnitValidate = {
	player = L["Player"],
	target = L["Target"],
	focus = L["Focus"],
	pet = L["Pet"],
	targettarget = L["Target of Target"],
	targettargettarget = L["ToT of Target"],
}

local eventUnitValidateDesc = {}

local tooltipValidate = {
	always = L["Always"],
	never = L["Never"],
	ooc = L["Out of Combat"],
}

local tooltipValidateDesc = {}

--- ========================================================= ---
---  Setup Options
--- ========================================================= ---
function DaHud_Module_Model:SetupOptions()
	DaHud.options.args.modelframes = {
		name = L["Model Frames"],
		desc = L["Change the Model Frame options."],
		type = 'group',
		args = {
		},
	}

	for i=1, self.db.profile.number do
		local frame = "hudmodel"..i
			
		self:UpdateMainOption(frame)
		self:UpdateNameOption(frame)
		self:UpdateShowOption(frame)
		self:UpdateFramestrataOption(frame)
		self:UpdateFramelevelOption(frame)
		self:UpdateWidthOption(frame)
		self:UpdateHeightOption(frame)
		self:UpdateScaleOption(frame)
		self:UpdatePosXOption(frame)
		self:UpdatePosYOption(frame)
		self:UpdateUnitOption(frame)
		self:UpdateButtonOption(frame)
		self:UpdateTooltipOption(frame)
	end
end

--- ========================================================= ---
---  Update Main Option
--- ========================================================= ---
function DaHud_Module_Model:UpdateMainOption(frame)
	local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])

	DaHud.options.args.modelframes.args[frame] = {
		name = name,
		desc = L["Change the Model Frame options."],
		type = 'group',
		args = {
		}
	}
end

--- ========================================================= ---
---  Update Name Option
--- ========================================================= ---
function DaHud_Module_Model:UpdateNameOption(frame)
	DaHud.options.args.modelframes.args[frame].args.name = {
		name = L["Name"],
		desc = L["Name the Frame."],
		type = 'text',
		usage = "<name>",
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return name
		end,
		set = function(value) 
			self:SaveOptions(frame, "name", value)
			self:SetupOptions()
		end,
	}
end

--- ========================================================= ---
---  Update Show Option
--- ========================================================= ---
function DaHud_Module_Model:UpdateShowOption(frame)
	DaHud.options.args.modelframes.args[frame].args.show = {
		name = L["Show"],
		desc = L["Show this Frame."],
		type = 'toggle',
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return show
		end,
		set = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			self:SaveOptions(frame, "show", not(show))
			self:UpdateAllFrames()
		end,
	}
end

--- ========================================================= ---
---  Update Framestrata Option
--- ========================================================= ---
function DaHud_Module_Model:UpdateFramestrataOption(frame)
	DaHud.options.args.modelframes.args[frame].args.framestrata = {
		name = L["Frame Strata"],
		desc = L["Choose the layer the model is drawn on."],
		type = 'text',
		validate = strataValidate,
		validateDesc = strataValidateDesc,
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return framestrata
		end,
		set = function(value) 
			self:SaveOptions(frame, "framestrata", value)
			self:UpdateAllFrames()
		end,
	}
end

--- ========================================================= ---
---  Update Framelevel Option
--- ========================================================= ---
function DaHud_Module_Model:UpdateFramelevelOption(frame)
	DaHud.options.args.modelframes.args[frame].args.framelevel = {
		name = L["Frame Level"],
		desc = L["Change the Frame Level it is drawn on."],
		type = 'range',
		min = 1,
		max = 12,
		step = 1,
		bigStep = 2,
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return framelevel
		end,
		set = function(value) 
			self:SaveOptions(frame, "framelevel", value)
			self:UpdateAllFrames()
		end,
	}
end

--- ========================================================= ---
---  Update Width Option
--- ========================================================= ---
function DaHud_Module_Model:UpdateWidthOption(frame)
	DaHud.options.args.modelframes.args[frame].args.width = {
		name = L["Width"],
		desc = L["Change the Width."],
		type = 'range',
		min = 0,
		max = 500,
		step = 1,
		bigStep = 20,
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return width
		end,
		set = function(value) 
			self:SaveOptions(frame, "width", value)
			self:UpdateAllFrames()
		end,
	}
end

--- ========================================================= ---
---  Update Height Option
--- ========================================================= ---
function DaHud_Module_Model:UpdateHeightOption(frame)
	DaHud.options.args.modelframes.args[frame].args.height = {
		name = L["Height"],
		desc = L["Change the Height."],
		type = 'range',
		min = 0,
		max = 500,
		step = 1,
		bigStep = 20,
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return height
		end,
		set = function(value) 
			self:SaveOptions(frame, "height", value)
			self:UpdateAllFrames()
		end,
	}
end

--- ========================================================= ---
---  Update Scale Option
--- ========================================================= ---
function DaHud_Module_Model:UpdateScaleOption(frame)
	DaHud.options.args.modelframes.args[frame].args.scale = {
		name = L["Scale"],
		desc = L["Change the Scale."],
		type = 'range',
		min = 0.25,
		max = 3,
		step = 0.01,
		bigStep = 0.05,
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return scale
		end,
		set = function(value) 
			self:SaveOptions(frame, "scale", value)
			self:UpdateAllFrames()
		end,
	}
end

--- ========================================================= ---
---  Update POS X Option
--- ========================================================= ---
function DaHud_Module_Model:UpdatePosXOption(frame)
	DaHud.options.args.modelframes.args[frame].args.posx = {
		name = L["Pos X"],
		desc = L["Change the X Position."],
		type = 'range',
		min = -500,
		max = 500,
		step = 1,
		bigStep = 20,
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return posx
		end,
		set = function(value) 
			self:SaveOptions(frame, "posx", value)
			self:UpdateAllFrames()
		end,
	}
end

--- ========================================================= ---
---  Update POS Y Option
--- ========================================================= ---
function DaHud_Module_Model:UpdatePosYOption(frame)
	DaHud.options.args.modelframes.args[frame].args.posy = {
		name = L["Pos Y"],
		desc = L["Change the Y Position."],
		type = 'range',
		min = -500,
		max = 500,
		step = 1,
		bigStep = 20,
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return posy
		end,
		set = function(value) 
			self:SaveOptions(frame, "posy", value)
			self:UpdateAllFrames()
		end,
	}
end

--- ========================================================= ---
---  Update Unit Option
--- ========================================================= ---
function DaHud_Module_Model:UpdateUnitOption(frame)
	DaHud.options.args.modelframes.args[frame].args.unit = {
		name = L["Event Unit"],
		desc = L["Choose which Unit the Event is monitoring and showing."],
		type = 'text',
		validate = eventUnitValidate,
		validateDesc = eventUnitValidateDesc,
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return unit
		end,
		set = function(value) 
			self:SaveOptions(frame, "unit", value)
			self:UpdateAllFrames()
		end,
	}
end

--- ========================================================= ---
---  Update Button Option
--- ========================================================= ---
function DaHud_Module_Model:UpdateButtonOption(frame)
	DaHud.options.args.modelframes.args[frame].args.button = {
		name = L["Button"],
		desc = L["Enable/Disable Button support on this Frame."],
		type = 'toggle',
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return button
		end,
		set = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			self:SaveOptions(frame, "button", not(button))
			self:UpdateAllFrames()
		end,
	}
end

--- ========================================================= ---
---  Update Tooltip Option
--- ========================================================= ---
function DaHud_Module_Model:UpdateTooltipOption(frame)
	DaHud.options.args.modelframes.args[frame].args.tooltip = {
		name = L["Tooltip"],
		desc = L["Choose when to show the Tooltip (Only works if Button is Enabled)."],
		type = 'text',
		validate = tooltipValidate,
		validateDesc = tooltipValidateDesc,
		get = function()
			local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
			return tooltip
		end,
		set = function(value) 
			self:SaveOptions(frame, "tooltip", value)
			self:UpdateAllFrames()
		end,
	}
end

--- ========================================================= ---
---  Save Options
--- ========================================================= ---
function DaHud_Module_Model:SaveOptions(frame, var, value)
	local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[frame])
	
	if var == "name" then
		name = value
	elseif var == "show" then
		show = value
	elseif var == "framestrata" then
		framestrata = value
	elseif var == "framelevel" then
		framelevel = value
	elseif var == "width" then
		width = value
	elseif var == "height" then
		height = value
	elseif var == "scale" then
		scale = value
	elseif var == "posx" then
		posx = value
	elseif var == "posy" then
		posy = value
	elseif var == "unit" then
		unit = value
	elseif var == "button" then
		button = value
	elseif var == "tooltip" then
		tooltip = value
	end
	
	self.db.profile[frame] = {name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip}
end	

--- ========================================================= ---
---  Create Frame
--- ========================================================= ---
function DaHud_Module_Model:CreateFrame(frametype, framename, parent, vals)
	local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[vals])
	local f = CreateFrame(frametype, framename, parent)

	f:SetWidth(width)
	f:SetHeight(height)
	f:SetScale(scale)
	f:SetPoint("Center", parent, "Center", posx, posy)
	f:SetFrameStrata(framestrata)
	f:SetFrameLevel(framelevel)
	
	f.unit = unit
	f.framename = framename
	
	f:SetAttribute("unit", unit)
	f:SetAttribute("shown", "unit")
	f:SetAttribute("useunit", unit)
	RegisterUnitWatch(f)
	
	f:SetScript("OnEvent", function(self)

		if event == "PLAYER_TARGET_CHANGED" then
			if self.unit ~= "target" and self.unit ~= "targettarget" then return end
		end
		if event == "PLAYER_FOCUS_CHANGED" then
			if self.unit ~= "focus" then return end
		end
		if event == "UNIT_TARGET" then
			if self.unit ~= "targettarget" then
				return
			else
				if arg1 ~= "target" then return end
			end
		end
		self:SetUnit(self.unit)
		self:RefreshUnit()
	end)
	
	f:RegisterEvent("DISPLAY_SIZE_CHANGED")
	f:RegisterEvent("UNIT_MODEL_CHANGED")
	f:RegisterEvent('PLAYER_TARGET_CHANGED')
	f:RegisterEvent('PLAYER_FOCUS_CHANGED')
	f:RegisterEvent('UNIT_TARGET')

	f:Show()

	return f
end

--- ========================================================= ---
---  Create Model Button
--- ========================================================= ---
function DaHud_Module_Model:CreateModelButton(type, framename, parent, vals)
	local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[vals])
	local f = CreateFrame(type, framename, parent, "SecureUnitButtonTemplate")

	f:SetWidth(width)
	f:SetHeight(height)
	f:SetScale(scale)
	f:SetPoint("Center", parent, "Center", posx, posy)
	f:SetFrameLevel(framelevel+1)

	f:RegisterForClicks("AnyUp")
	
	f:SetScript("OnEnter", function(self)
		if self.tt == "always" or (self.tt == "ooc" and not(InCombatLockdown())) then
			GameTooltip:SetOwner(self, "ANCHOR_NONE")
			GameTooltip:SetPoint("BOTTOM", self, "TOP", 0, 20)
			GameTooltip:SetUnit(unit)
			GameTooltip:Show()
		end
	end)
		
	f:SetScript("OnLeave", function(self) 
		if(GameTooltip:IsOwned(self)) then
			GameTooltip:Hide()
		end
	end)
	
	f:SetScript("OnEvent", function(self)
	
	end)

	f.tt = tooltip
	f.unit = unit
	f:SetAttribute("*type1", "target")
	f:SetAttribute("*type2", "menu")
	f:SetAttribute("unit", unit)
	f:SetAttribute("shown", "unit")
	f:SetAttribute("useunit", unit)
	
	if unit == "player" then
		f.menu = function(self)
			ToggleDropDownMenu(1, nil, PlayerFrameDropDown, "cursor", 0, 0)
		end
	elseif unit == "target" then
		f.menu = function(self)
			ToggleDropDownMenu(1, nil, TargetFrameDropDown, "cursor", 0, 0)
		end
	elseif unit == "focus" then
		f.menu = function(self)
			ToggleDropDownMenu(1, nil, FocusFrameDropDown, "cursor", 0, 0)
		end
	elseif unit == "pet" then
		f.menu = function(self)
			ToggleDropDownMenu(1, nil, PetFrameDropDown, "cursor", 0, 0)
		end
	end
	
	RegisterUnitWatch(f)
	
	ClickCastFrames = ClickCastFrames or {}
	ClickCastFrames[f] = true
	
	f:Show()
end

--- ========================================================= ---
---  Create Frames
--- ========================================================= ---
function DaHud_Module_Model:CreateFrames()
	for i=1, self.db.profile.number do
		self:CreateFrame("PlayerModel", "DaHudModel"..i, getglobal("DaHudFrame"), "hudmodel"..i)
		self:CreateModelButton("Button", "DaHudModel"..i.."Button", getglobal("DaHudFrame"), "hudmodel"..i)
	end
end

--- ========================================================= ---
---  Update All Frames
--- ========================================================= ---
function DaHud_Module_Model:UpdateAllFrames()
	for i=1, self.db.profile.number do
		self:UpdateFrame("DaHudModel"..i, "hudmodel"..i)
		self:UpdateButton("DaHudModel"..i, "hudmodel"..i)
		self:UpdateModel("DaHudModel"..i, "hudmodel"..i)
	end
end

--- ========================================================= ---
---  Update Frame
--- ========================================================= ---
function DaHud_Module_Model:UpdateFrame(framename, vals)
	local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[vals])
	local f = getglobal(framename)
	
	if DaHud_ConfigMode then
		unit = "player"
	end
	
	f:SetWidth(width)
	f:SetHeight(height)
	f:SetScale(scale)
	f:SetPoint("Center", getglobal("DaHudFrame"), "Center", posx, posy)
	f:SetFrameStrata(framestrata)
	f:SetFrameLevel(framelevel)
	
	f.unit = unit
	f.framename = framename
	
	f:SetAttribute("unit", unit)
	f:SetAttribute("shown", "unit")
	f:SetAttribute("useunit", unit)
	
	self:UpdateModel(framename, vals)
	
	if show then
		RegisterUnitWatch(f)
	else
		UnregisterUnitWatch(f)
		f:Hide()
	end	
end

--- ========================================================= ---
---  Update Button
--- ========================================================= ---
function DaHud_Module_Model:UpdateButton(framename, vals)
	local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[vals])
	local f = getglobal(framename.."Button")
	
	if DaHud_ConfigMode then
		unit = "player"
	end
	
	f:SetWidth(width)
	f:SetHeight(height)
	f:SetScale(scale)
	f:SetPoint("Center", getglobal("DaHudFrame"), "Center", posx, posy)
	f:SetFrameLevel(framelevel+1)
	
	f.tt = tooltip
	f.unit = unit
	
	f:SetAttribute("*type1", "target")
	f:SetAttribute("*type2", "menu")
	f:SetAttribute("unit", unit)
	f:SetAttribute("shown", "unit")
	f:SetAttribute("useunit", unit)
	
	if unit == "player" then
		f.menu = function(self)
			ToggleDropDownMenu(1, nil, PlayerFrameDropDown, "cursor", 0, 0)
		end
	elseif unit == "target" then
		f.menu = function(self)
			ToggleDropDownMenu(1, nil, TargetFrameDropDown, "cursor", 0, 0)
		end
	elseif unit == "focus" then
		f.menu = function(self)
			ToggleDropDownMenu(1, nil, FocusFrameDropDown, "cursor", 0, 0)
		end
	elseif unit == "pet" then
		f.menu = function(self)
			ToggleDropDownMenu(1, nil, PetFrameDropDown, "cursor", 0, 0)
		end
	end
	
	if button then
		RegisterUnitWatch(f)
		ClickCastFrames = ClickCastFrames or {}
		ClickCastFrames[f] = true
	else
		UnregisterUnitWatch(f)
		ClickCastFrames = ClickCastFrames or {}
		ClickCastFrames[f] = nil
		f:Hide()
	end
end

--- ========================================================= ---
---  Update Model
--- ========================================================= ---
function DaHud_Module_Model:UpdateModel(framename, vals)
	local name, show, framestrata, framelevel, width, height, scale, posx, posy, unit, button, tooltip = unpack(self.db.profile[vals])
	local f = getglobal(framename)
	
	if DaHud_ConfigMode then
		unit = "player"
	end
	
	f:SetUnit(unit)
	f:RefreshUnit()
end